﻿using System;
using System.Collections.ObjectModel;
using System.ServiceModel;
using System.Threading;
using System.Windows;
using PEM.Silverlight.UI.MoneyTrackingServiceReference;

namespace PEM.Silverlight.UI
{
    public partial class MainPage
    {
        #region Dependency Property

        public ObservableCollection<Expense> Expenses
        {
            get;
            set;
        }


        public ObservableCollection<Category> Categories
        {
            get;
            set;
        }

        #endregion

        public MainPage()
        {
            InitializeComponent();
            Categories = new ObservableCollection<Category>();
            Expenses = new ObservableCollection<Expense>();
        }

        #region AsyncronousCall
        private void ASyncronousCall(object sender, RoutedEventArgs e)
        {
            AddCategory();
        }
        public void AddCategory()
        {
            var client = new MoneyServiceClient();
            var category = new Category();
            //fill category attributes here
            client.AddCategoryAsync(category);
            client.AddCategoryCompleted += ClientAddCategoryCompleted;
        }

        void ClientAddCategoryCompleted(object sender, AddCategoryCompletedEventArgs e)
        {
            ServiceResponse serviceResponse = e.Result;
            if (serviceResponse.IsSuccess)
                Categories.Add((Category)serviceResponse.Result);
        }
        #endregion

        #region Syncronous call
        private void SyncronousCall(object sender, RoutedEventArgs e)
        {
            ThreadPool.QueueUserWorkItem(AddExpenseInServer);

        }

        private void AddExpenseInServer(object state)
        {
            Expense addedExpense = AddExpense();
            Dispatcher.BeginInvoke(() =>
                                       {
                                           StatusMessage.Content = "Expense is been Added";
                                           Expenses.Add(addedExpense);
                                       });
        }

        private Expense AddExpense()
        {
            var asyncCallStatus = new AsyncCallStatus<AddExpenseCompletedEventArgs>();
            var client = new MoneyServiceClient();
            client.AddExpenseCompleted += ClientAddExpenseCompleted;
            client.AddExpenseAsync(new Expense(), asyncCallStatus);
            _autoResetEvent.WaitOne();
            if (asyncCallStatus.CompletedEventArgs.Error != null)
            {
                throw asyncCallStatus.CompletedEventArgs.Error;
            }
            var serviceResponse = asyncCallStatus.CompletedEventArgs.Result;
            if (serviceResponse.IsSuccess)
            {
                return serviceResponse.Result as Expense;
            }
            else
                return null;
        }

        void ClientAddExpenseCompleted(object sender, AddExpenseCompletedEventArgs e)
        {
            var status = e.UserState as AsyncCallStatus<AddExpenseCompletedEventArgs>;
            if (status != null) status.CompletedEventArgs = e;
            _autoResetEvent.Set();
        }

        private readonly AutoResetEvent _autoResetEvent = new AutoResetEvent(false);

        public class AsyncCallStatus<T>
        {
            public T CompletedEventArgs { get; set; }
        }
        #endregion

        private void UsingChanelFactory(object sender, RoutedEventArgs e)
        {
            var basicHttpBinding = new BasicHttpBinding();
            var endpointAddress = new EndpointAddress("http://localhost/MoneyTrackingWeb/MoneyTrackingService.svc");
            var moneyService = new ChannelFactory<MoneyTracking.Service.IMoneyService>(basicHttpBinding, endpointAddress).CreateChannel();
            moneyService.BeginAddCategory(new MoneyTracking.Common.Category(), ASyncronousCallBack, moneyService);
        }

        private void ASyncronousCallBack(IAsyncResult ar)
        {
            if(ar.IsCompleted)
            {
                MoneyTracking.Common.ServiceResponse serviceResponse = ((MoneyTracking.Service.IMoneyService)ar.AsyncState).EndAddCategory(ar);
                if(serviceResponse.IsSuccess)
                {
                    //do your work here
                }
            }
        }
    }
}
